<?php

class Helper_Menu
{
    /**
     * @property array
     *
     */
    protected $_config = array();

    /**
     * @property int
     */
    protected $_maxLevel = 3;

    /**
     * @param string $menu
     * @param string $submenu
     * @return array with multi level
     */
    public function getItems($menu)
    {
        $table = Agis::getTable('core@menu.item');

        $select = $table -> select() -> where('enabled=1') -> order('priority ASC') -> limit(100);

        if (!empty($menu))
        {
            $select -> where('menu=?', (string)$menu);
        }

        $rows = $table -> fetchAll($select) -> toArray();

        // multi level process.

        $result = array();

        //
        $map0 = array();
        $map1 = array();
        $map2 = array();

        // build menu for level 1
        foreach ($rows as $index => $row)
        {
            if ($row['parent_id'] == 0)
            {
                $result[] = self::processMenuItem($row);
                $map0[$row['id']] = count($result) - 1;
                unset($rows[$index]);
            }
        }

        // build menu for level 2
        foreach ($rows as $index => $row)
        {
            if (isset($map0[$row['parent_id']]))
            {
                $index0 = $map0[$row['parent_id']];
                $result[$index0]['children'][] = self::processMenuItem($row);
                $map1[$row['parent_id']] = count($result[$index0]['children']) - 1;
                unset($rows[$index]);
            }
        }

        // flattern what you need to see the problem.

        return $result;
    }

    /**
     * @param array $row
     * @return array
     */
    static public function processMenuItem($row)
    {
        if ($row['plugin'] && count($plugin = explode(':', $row['plugin'])) == 2)
        {
            $row['plugin'] = $plugin;
        }
        return $row;
    }

    /**
     * @param array $config
     * @param string $menu
     * @param string $submenu
     * @param int max_level
     * @return xhtml
     */
    public function render($menu, $config, $max_level = 2)
    {
        $items = $this -> getItems($menu);

        // process menu to know what is happend with menu items.
        $level = 0;
        $this -> _maxLevel = $max_level;
        $this -> _config = $config;

        $xhtml = '';
        foreach ($items as $item)
        {
            $xhtml .= $this -> renderItem($item, $level);
        }

        return sprintf('<ul class="%s">%s</ul>', $this -> getConfig('menuClass', 'uiMenu'), $xhtml);
    }



    /**
     * get config by name
     * @param string $name
     * @param mixed $default
     * @return mixed
     */
    public function getConfig($name, $default = '')
    {
        return isset($this -> _config[$name]) ? $this -> _config[$name] : $default;
    }

    /**
     * @param  array $items
     * @return string
     */
    public function renderSubmenu($items, $level)
    {
        // check if empty item
        if (empty($items))
        {
            return '';
        }

        $xhtml = '';
        foreach ($items as $item)
        {
            $xhtml .= $this -> renderItem($item, $level + 1);
        }
        return sprintf('<ul>%s</ul>', $xhtml, $level);
    }

    /**
     * render a menu item
     * @param array $item {children: array(), plugin: mixed, label, menu,
     * submenu, level}
     */
    public function renderItem($item, $level = 0)
    {
        if ($item['plugin'])
        {
            $item = call_user_func($item['plugin'], $item);
        }
        if ($item == false)
        {
            return '';
        }

        $hasChild = isset($item['children']) && !empty($item['children']) && $level < $this -> _maxLevel;
        $url = Agis::get('baseUrl') . $item['uri'];
        $ul = '';

        $li = sprintf('<a href="%s">%s</a>', $url, $item['label']);

        if ($hasChild)
        {
            $ul = $this -> renderSubmenu($item['children'], $level);
        }

        return sprintf('<li class="%s">%s%s</li>', $item['name'], $li, $ul);
    }

}
